package cz.movie.subRenamer.worker.impl;

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.zip.ZipException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cz.movie.subRenamer.model.FileRepresentation;
import cz.movie.subRenamer.model.LanguageSupport;
import cz.movie.subRenamer.util.Action;
import cz.movie.subRenamer.util.FileNameUtil;
import cz.movie.subRenamer.util.JUnrarUtil;
import cz.movie.subRenamer.util.ZipUtil;
import cz.movie.subRenamer.worker.SubtitleWorker;

public class SubtitleWorkerImpl implements SubtitleWorker {
	static final Logger logger = LoggerFactory.getLogger(SubtitleWorkerImpl.class);
	public static final String NO_LANG_FOUND_FOR_ARCHIVE = "noLanguageFoundBySubRenamerForArchive";
	List<LanguageSupport> listOfLanguages;
	final static String[] delimiters = { ".", "-", "_" };

	public SubtitleWorkerImpl(List<LanguageSupport> listOfLanguages) {
		this.listOfLanguages = listOfLanguages;
	}

	public void extractAllSubtitles(File basedir) {
		FileNameUtil.onEachFileDoStuff(basedir, new Action<File>() {
			public void doStuff(File file) {
				if (FileNameUtil.isArchiveFile(file.getName())) {
					try {
						logger.info("trying extract archive {} ", file.getName());
						deteckLanguageAndExtract(file);
						logger.info("extract successful");
					} catch (Exception e) {
						logger.info("cannot extract file: {} " + file.getAbsolutePath());
						logger.debug(e.getMessage());
					}
				}
			}
		});
	}

	private void deteckLanguageAndExtract(File file) throws ZipException, IOException {
		LanguageSupport lang = findLanguageInPartOfTheName(file.getName());

		String dirName;
		if (lang != null) {
			dirName = lang.getProperName();
		} else {
			dirName = NO_LANG_FOUND_FOR_ARCHIVE;
		}

		File dir = new File(file.getParentFile(), dirName);
		for (int i = 1; dir.exists(); i++) {
			dir = new File(file.getParentFile(), dirName + i);
		}
		dir.mkdir();
		try {
			logger.debug("trying extract with standard java");
			ZipUtil.extraxtZipToDir(file, dir, true);
		} catch (Exception e) {
			logger.debug("extract with standard java failed", e);
			logger.debug("trying extract with junrar");
			JUnrarUtil.extractArchive(file, dir);
		}
	}

	public void addLanguageToSubtitles(List<FileRepresentation> listFiles) {
		for (FileRepresentation fr : listFiles) {
			if (!fr.hasSubtitleExtension()) {
				continue;
			}
			String name = fr.getFile().getName();
			LanguageSupport founded = findLanguageInPartOfTheName(name);
			if (founded == null) {
				founded = checkParentDir(listOfLanguages, fr);
				if (founded == null) {
					continue;
				}
			}
			fr.setLanguage(founded.getProperName());
		}
	}

	private LanguageSupport checkParentDir(List<LanguageSupport> listOfLanguages, FileRepresentation fr) {
		String parentName = fr.getFile().getParentFile().getName();
		for (LanguageSupport l : listOfLanguages) {
			if (parentName.startsWith(l.getProperName())) {
				return l;
			}
		}
		return null;
	}

	private LanguageSupport searchForLang(List<LanguageSupport> listOfLanguages, String[] nameSplits) {
		for (LanguageSupport l : listOfLanguages) {
			for (int i = nameSplits.length - 1; i >= 0; i--) {
				if (l.isStringInLang(nameSplits[i])) {
					return l;
				}
			}
		}
		return null;
	}

	private LanguageSupport findLanguageInPartOfTheName(String name) {
		LanguageSupport founded = null;
		for (String delimiter : delimiters) {
			name = name.replace(delimiter, " ");
		}
		founded = searchForLang(listOfLanguages, name.split("\\s+"));
		return founded;
	}

}
